﻿using AutoMapper;
using ImoviesBlazor.Server.Helpers;
using ImoviesBlazor.Server.Repository;
using ImoviesBlazor.Shared.Dtos;
using ImoviesBlazor.Shared.Entities;
using ImoviesBlazor.Shared.Utils;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Security.Cryptography;
using System.Text;

namespace ImoviesBlazor.Server.Controllers
{

    /// <summary>
    /// 电视剧控制器
    /// </summary>
    [ApiController]
    [Route("api/[controller]")]
    public class TeleplayController : ControllerBase
    {
        private readonly ITeleplayRepository _teleplayRepository;
        private readonly IMapper _mapper;

        public TeleplayController(ITeleplayRepository teleplayRepository, IMapper mapper)
        {
            this._teleplayRepository = teleplayRepository;
            this._mapper = mapper;
        }

        /// <summary>
        /// 获取所有年份
        /// </summary>
        /// <returns></returns>
        [HttpGet("years")]
        public async Task<ActionResult<IEnumerable<uint>>> GetAllYears()
        {
            // 先从缓存中读取
            var cacheYears = CacheUtils.GetData<List<uint>>(CacheKeyConst.TELEPLAY_ALL_YEARS);
            if (cacheYears != null)
            {
                return Ok(cacheYears);
            }

            var years = await _teleplayRepository.GetAllYearsAsync();

            // 设置缓存
            CacheUtils.SetData<List<uint>>(CacheKeyConst.TELEPLAY_ALL_YEARS, years.Distinct().ToList());

            return Ok(years.Distinct());
        }

        /// <summary>
        /// 分页获取数据
        /// </summary>
        /// <param name="pageSize">页大小</param>
        /// <param name="pageNum">页码</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<ActionResult<IEnumerable<TeleplayDataList>>> GetList([FromQuery] int pageSize, [FromQuery] int pageNum)
        {
            string cacheKey = $"{CacheKeyConst.TELEPLAY_PAGINATION_LIST}{pageSize}{pageNum}";
            // 先从缓存中读取
            var cacheData = CacheUtils.GetData<PaginationList<TeleplayDataList>>(cacheKey);
            if (cacheData != null)
            {
                return Ok(cacheData);
            }

            var ts = await _teleplayRepository.GetListAsync(pageSize, pageNum);

            var tsDtolist = _mapper.Map<IEnumerable<TeleplayDto>>(ts);
            List<TeleplayDataList> list = new List<TeleplayDataList>();
            var gy = tsDtolist.GroupBy(x => x.Year).ToList();

            foreach (var item in gy)
            {
                list.Add(new TeleplayDataList
                {
                    Year = item.Key,
                    List = item.ToList()
                });
            }

            var total = await _teleplayRepository.GetTotal();
            var data = new PaginationList<TeleplayDataList>
            {
                Data = list,
                Total = total,
            };

            // 设置缓存
            CacheUtils.SetData<PaginationList<TeleplayDataList>>(cacheKey, data);

            return Ok(data);
        }


        /// <summary>
        /// 获取所有视频列表
        /// </summary>
        /// <returns></returns>
        [HttpGet("all")]
        public async Task<ActionResult<IEnumerable<TeleplayDataList>>> GetAll()
        {
            // 先从缓存中读取
            var cacheData = CacheUtils.GetData<List<TeleplayDto>>(CacheKeyConst.TELEPLAY_ALL_LIST);
            if (cacheData != null)
            {
                return Ok(cacheData);
            }

            var ts = await _teleplayRepository.GetAllListAsync();
            var tsDtoList = _mapper.Map<IEnumerable<TeleplayDto>>(ts);

            // 设置缓存
            CacheUtils.SetData<List<TeleplayDto>>(CacheKeyConst.TELEPLAY_ALL_LIST, tsDtoList.ToList());

            return Ok(tsDtoList);
        }


        /// <summary>
        /// 获取视频链接列表
        /// </summary>
        /// <param name="vid"></param>
        /// <returns></returns>
        [HttpGet("vlist/{vid}")]
        public async Task<ActionResult<IEnumerable<TeleplayVlinkDto>>> GetVlinkList(string vid)
        {
            string cacheKey = $"{CacheKeyConst.TELEPLAY_PLAYLINK_LIST}{vid}";
            // 先从缓存中读取
            var cacheData = CacheUtils.GetData<List<TeleplayVlinkDto>>(cacheKey);
            if (cacheData != null)
            {
                return Ok(cacheData);
            }

            var vlinks = await _teleplayRepository.GetVlinkList(vid);
            var data = _mapper.Map<IEnumerable<TeleplayVlinkDto>>(vlinks);

            // 设置缓存
            CacheUtils.SetData<List<TeleplayVlinkDto>>(cacheKey, data.ToList());

            return Ok();
        }

        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="teleplay"></param>
        /// <returns></returns>
        [Authorize]
        [HttpPost]
        public async Task<ActionResult> AddTeleplay([FromBody] TeleplayForCreateDto teleplay)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest();
            }
            var t = _mapper.Map<Teleplay>(teleplay);
            byte[] bytes = MD5.HashData(Encoding.UTF8.GetBytes(teleplay.Name));
            t.Id = BitConverter.ToString(bytes).Replace("-", "");
            _teleplayRepository.AddTeleplay(t);
            bool res = await _teleplayRepository.SaveAsync();
            if (!res)   //保存失败
            {
                Response.StatusCode = 500;
                return Content("操作失败");
            }
            return Ok();
        }


        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="teleplay"></param>
        /// <returns></returns>
        [Authorize]
        [HttpPut]
        public async Task<ActionResult> UpdateTeleplay([FromBody] TeleplayForUpdateDto teleplay)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest();
            }
            var t = _mapper.Map<Teleplay>(teleplay);
            _teleplayRepository.UpdateTeleplay(t);
            bool res = await _teleplayRepository.SaveAsync();
            if (!res)   //保存失败
            {
                Response.StatusCode = 500;
                return Content("操作失败");
            }
            return Ok();
        }


        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [Authorize]
        [HttpDelete("{id}")]
        public async Task<ActionResult<bool>> DeleteTeleplay([FromRoute] string id)
        {
            await _teleplayRepository.DeleteTeleplay(id);
            bool res = await _teleplayRepository.SaveAsync();
            if (!res)   //保存失败
            {
                Response.StatusCode = 500;
                return Content("操作失败");
            }
            return Ok();
        }
    }
}
